package com.wquick.base.utils.permissionFlow.impl

import android.app.Application
import android.content.Context
import androidx.annotation.VisibleForTesting
import com.wquick.base.utils.permissionFlow.MultiplePermissionState
import com.wquick.base.utils.permissionFlow.PermissionFlow
import com.wquick.base.utils.permissionFlow.PermissionState
import com.wquick.base.utils.permissionFlow.internal.ApplicationStateMonitor
import com.wquick.base.utils.permissionFlow.watchmen.PermissionWatchmen
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.StateFlow

/** Default implementation of a [PermissionFlow] */
internal class PermissionFlowImpl
@VisibleForTesting
constructor(
    private val watchmen: PermissionWatchmen,
) : PermissionFlow {

    override fun getPermissionState(permission: String): StateFlow<PermissionState> {
        return watchmen.watchState(permission)
    }

    override fun getMultiplePermissionState(
        vararg permissions: String
    ): StateFlow<MultiplePermissionState> {
        return watchmen.watchMultipleState(permissions.toList().toTypedArray())
    }

    override fun notifyPermissionsChanged(vararg permissions: String) {
        watchmen.notifyPermissionsChanged(permissions.toList().toTypedArray())
    }

    override fun startListening() {
        watchmen.wakeUp()
    }

    override fun stopListening() {
        watchmen.sleep()
    }

    internal companion object {
        @Volatile
        var instance: PermissionFlowImpl? = null
            private set

        @Synchronized
        fun init(context: Context, dispatcher: CoroutineDispatcher) {
            if (instance == null) {
                val monitor = ApplicationStateMonitor(context.applicationContext as Application)
                val watchmen =
                    PermissionWatchmen(
                        appStateMonitor = monitor,
                        dispatcher = dispatcher,
                    )
                instance = PermissionFlowImpl(watchmen)
            }
        }
    }
}